<template>
  <div class="container">
    <div class="left-area" v-show="AreaVisible.left">
      <slot name="drawerLeftArea"></slot>
    </div>
    <div class="left-btn" v-stream:click="leftBtn$"></div>
    <div class="middle-area">
      <div></div>
      <div class="middle-btn"></div>
      <div></div>
    </div>
    <div class="right-btn" v-stream:click="rightBtn$"></div>
    <div class="right-area" v-show="AreaVisible.right">
      <slot name="rightArea" />
    </div>
  </div>
</template>
<style lang="less" scoped>
.container {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: row;
  .left-area {
    width: 200px;
    height: 100%;
    background-color: green;
    float: left;
  }
  .left-btn,
  .right-btn {
    width: 10px;
    height: 100%;
    background-color: red;
  }
  .middle-area {
    width: calc(100% - 200px - 200px);
    height: 100%;
  }
  .right-area {
    width: 200px;
    height: 100%;
    background-color: blue;
    float: right;
  }
}
</style>
<script>
import { Observable } from "rxjs";
import { merge } from "rxjs/operators";
import { forEach, cloneDeep } from "lodash";

export default {
  name: "drawer",
  data() {
    return {
      mainArea: null,
      rightBtn: null,
      leftArea: null,
      middleArea: null,
      AreaVisible: {},
    };
  },
  props: {
    areaVisible: {
      type: Object,
      default: () => {
        return {
          left: true,
          right: true,
        };
      },
      validator(object) {
        object.left = object?.left === undefined ? true : object.left;
        object.right = object?.right === undefined ? true : object.right;
        forEach(object, (value) => {
          if (!(value instanceof Boolean)) {
            value = true;
          }
        });
        return object;
      },
    },
    leftAreaWidth: {
      type: Number,
      default: 200,
    },
    middleAreaWidth: {
      type: Number,
      default: 0,
    },
    rightAreaWidth: {
      type: Number,
      default: 200,
    },
    btnWidth: {
      type: Number,
      default: 10,
    },
  },
  domStreams: ["leftBtn$", "rightBtn$"],
  subscriptions() {
    return {
      leftOrRightBtnClick: new Observable().pipe(
        merge(
          this.leftBtn$.map((e) => e.event.target.className),
          this.rightBtn$.map((e) => e.event.target.className)
        )
      ),
    };
  },
  watch: {
    areaVisible: {
      handler(nval) {
        this.AreaVisible = cloneDeep(nval);
      },
      deep: true,
      immediate: true,
    },
  },
  mounted() {
    this.$nextTick(() => {
      this.mainArea = document.getElementsByClassName("main")[0];
      this.rightArea = document.getElementsByClassName("right-area")[0];
      this.leftArea = document.getElementsByClassName("left-area")[0];
      this.middleArea = document.getElementsByClassName("middle-area")[0];

      this.setMiddleWidth();
    });

    this.$observables.leftOrRightBtnClick.subscribe((className) => {
      this.handleBtnClick(className);
    });
  },
  methods: {
    setMiddleWidth() {
      const { rightArea, leftArea, middleArea, btnWidth } = this;

      this.$nextTick(() => {
        // !!!
        middleArea.style.width = "auto";

        const rwidth = rightArea.clientWidth;
        const lwidth = leftArea.clientWidth;

        middleArea.style.width = `calc(100% - ${rwidth}px - ${lwidth}px - ${btnWidth}px * 2)`;
      });
    },
    handleBtnClick(className) {
      const { rightArea, leftArea } = this;

      if (className == "right-btn") {
        rightArea.style.width = this.AreaVisible.right
          ? "0px"
          : this.rightAreaWidth + "px";
        this.AreaVisible.right = !this.AreaVisible.right;
      } else if (className == "left-btn") {
        leftArea.style.width = this.AreaVisible.left
          ? "0px"
          : this.leftAreaWidth + "px";
        this.AreaVisible.left = !this.AreaVisible.left;
      }
      this.setMiddleWidth();
    },
    visibleChange(area, visible) {
      if (area === "left") {
        this.AreaVisible.left = !visible;
        this.handleBtnClick("left-btn");
      } else if (area === "right") {
        this.AreaVisible.right = !visible;
        this.handleBtnClick("right-btn");
      }
    },
    containerChange() {
      this.setMiddleWidth();
    },
  },
};
</script>
